package aspects;

import generique.Log;

import java.rmi.Naming;

import client.KernelClient;



/**
 * 
 * Aspect permettant de logger l'activité du client.
 * 
 * @author Valentin Brémond
 * 
 * @version 1.0
 *
 */
public privileged aspect LogClientAspect
{
	// On récupère l'instance de log
	Log log = Log.getInstance ();
	
	
	
	/**
	 * Au démarrage du client.
	 */
	KernelClient around () : call (KernelClient.new (..))
	{
		log.info ("Démarrage du client...");
		
		return proceed ();
	}
	
	
	
	/**
	 * Lors du binding.
	 */
	before (String urlServeur) : call (* Naming.lookup (String)) && args (urlServeur) && this (KernelClient)
	{
		log.info ("Tentative de connexion au serveur '" + urlServeur + "'...");
	}
	after (String urlServeur) returning : call (* Naming.lookup (String)) && args (urlServeur) && this (KernelClient)
	{
		log.info ("Client connecté au serveur '" + urlServeur + "'.");
	}
	
	
	
	/**
	 * À l'extinction du client.
	 */
	before () : call (* System.exit (..))
	{
		if (thisEnclosingJoinPointStaticPart.getSignature ().getDeclaringType ().equals (KernelClient.class))
		{
			log.info ("Arrêt du client.");
		}
	}
	
	
	
	/**
	 * Lors du calcul Diffie-Hellman.
	 */
	void around () : call (void KernelClient.diffieHellman ())
	{
		KernelClient kernelClient = (KernelClient) thisJoinPoint.getTarget ();
		
		log.info ("Tentative de génération de clé symétrique...");
		
		proceed ();
		
		log.info ("Valeurs générées : G = " + kernelClient.G + ", n = " + kernelClient.n + ", X = " + kernelClient.X + ".");
		log.info ("Clé symétrique calculée par le client : " + kernelClient.cleDiffieHellman);
	}
	
	
	
	/**
	 * Lors de la vérification d'authenticité.
	 */
	boolean around () : execution (boolean KernelClient.verifierAuthenticite ())
	{
		boolean retour;
		
		log.info ("Tentative d'authentification au serveur...");
		
		retour = proceed ();
		
		if (retour)
		{
			log.info ("Le client est bien authentifié au serveur distant. La connexion est sécurisée.");
		}
		else
		{
			log.warning ("Impossible de s'authentifier au serveur distant.");
		}
		
		return retour;
	}
	
	
	
	/**
	 * Lors de l'envoi d'une requête.
	 */
	String around (String requete) : execution (String KernelClient.effectuerRequete (String)) && args (requete)
	{
		String retour;
		
		log.info ("Envoi d'une requête au client : '" + requete + "'.");
		
		retour = proceed (requete);
		
		if (retour == null)
		{
			log.error ("Vous ne pouvez pas faire de requête sans être authentifié.");
		}
		else
		{
			log.info ("Réponse du serveur : '" + retour + "'.");
		}
		
		return retour;
	}
}
